/*
Module : FTPTRANSFERER.H
Purpose: Defines the interface for an MFC class which provides a wrapping for FTP transfers in a 
         synchronous manner via Wininet

Copyright (c) 2006 - 2007 by PJ Naughter (Web: www.naughter.com, Email: pjna@naughter.com)

All rights reserved.

Copyright / Usage Details:

You are allowed to include the source code in any product (commercial, shareware, freeware or otherwise) 
when your product is released in binary form. You are allowed to modify the source code in any way you want 
except you cannot modify the copyright details at the top of each module. If you want to distribute source 
code with your application, then you are only allowed to distribute versions released by the author. This is 
to maintain a single distribution point for the source code. 

*/


////////////////////////////////// Macros ///////////////////////////

#pragma once

#ifndef __FTPTRANSFERER_H__
#define __FTPTRANSFERER_H__

#ifndef CFTPTRANSFERER_EXT_CLASS
#define CFTPTRANSFERER_EXT_CLASS
#endif


/////////////////////////// Classes /////////////////////////////////

//The synchronous downloading API which CFTPTransferDlg incorporates. If you do not want
//any UI then you can use this class directly
class CFTPTRANSFERER_EXT_CLASS CFTPTransferer
{
public:
//Constructors / Destructors
  CFTPTransferer();
  ~CFTPTransferer();
  
//Methods
  BOOL      Transfer();  
  BOOL      DeleteDownloadedFile();
  void      AttachSession(HINTERNET hInternetSession);
  HINTERNET DetachSession();   

//Enums
  enum ConnectionType
  {
    UsePreConfig,  
    DirectToInternet,
    UseProxy,
  };

//Member variables
  BOOL           m_bDownload;           //TRUE if it's a download, FALSE if an upload
  CString        m_sServer;             //e.g. "ftp.microsoft.com"
  CString        m_sRemoteFile;         //e.g. "/pub/somefile.ext"
  CString        m_sLocalFile;          //e.g. "c:\temp\somfile.txt"
  CString        m_sUserName;           //Username to login to the server with
  CString        m_sPassword;           //password to login to the server with
  INTERNET_PORT  m_nPort;               //If you want to change the port to make access on, by default it will be 21
  BOOL           m_bBinary;             //TRUE if binary transfer, FALSE for ascii transfer
  BOOL           m_bPasv;               //should a PASV connection be used
  double		     m_dbLimit;             //For BANDWIDTH Throptling, The value in Bytes / Second to limit the connection to
  DWORD          m_dwConnectionTimeout; //The connection timeout to use (in milliseconds), (Specify a value of 0 not to use a connection timeout)
  CString        m_sUserAgent;          //The User agent to use
  CString        m_sProxyServer;        //The proxy server to use
  ConnectionType m_ConnectionType;      //The connection type to use  
  DWORD          m_dwReadBufferSize;    //The size of the receive buffer when we read the HTTP response

protected:
//Member variables
  HINTERNET        m_hInternetSession;
  HINTERNET        m_hFTPConnection;
  HINTERNET        m_hFTPFile;
  volatile LONG    m_lAbort;
  CFile            m_LocalFile;
  CCriticalSection m_csHandles;             //Critical section we use to serialize access to the Wininet handles
  DWORD            m_dwTempError;
 
//Static methods
  static void CALLBACK _OnWininetStatusCallBack(HINTERNET hInternet, DWORD_PTR dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInformation, DWORD dwStatusInformationLength);
  static CString GetErrorMessage(DWORD dwError);
  static UINT _MakeConnectionThread(LPVOID pParam);
  
//Standard methods
  void ReleaseHandles();
  void SetAbort();
  BOOL _Transfer();  

//Virtual methods
  virtual BOOL CreateSession();
  virtual BOOL CreateConnection();
  virtual BOOL CreateRequest();
  virtual UINT MakeConnection();
  virtual void OnWininetStatusCallBack(HINTERNET hInternet, DWORD dwInternetStatus, LPVOID lpvStatusInformation, DWORD dwStatusInformationLength);
  virtual void HandleError(UINT nID, DWORD dwError);
  virtual void SetStatus(UINT nID);
  virtual void SetStatus(UINT nID, LPCTSTR lpsz1);
  virtual void SetStatus(LPCTSTR pszStatus);
  virtual BOOL Abort();
  virtual void OnProgress(ULONGLONG nBytesRead, BOOL bGotFileSize, ULONGLONG nTotalBytesToRead);
  virtual BOOL OnTransferData(const BYTE* pbyData, DWORD dwSize);
  virtual BOOL GetRemoteFileLength(ULONGLONG& dwFileSize);
};

#endif //__FTPTRANSFERER_H__
